# encoding: utf-8
"""
@author: youfeng
@file: app_init.py
@time: 2018/9/16 下午2:20
"""
import json

from flask import Flask, request

from ext.response_wrap import ResponseWrap
from views.gsxt_view import bp as gsxt_bp
from views.news_view import bp as news_bp
from views.shixin_view import bp as shixin_bp
from views.wenshu_view import bp as wenshu_bp
from views.zhixing_view import bp as zhixing_bp


class AppInit(object):
    def __init__(self, log):
        self.log = log

        self.__app = self.__create_app()

    def get_app(self):
        return self.__app

    def __create_app(self, name=None):
        app = Flask(name or __name__)

        # 打印请求信息
        app.after_request(self.__print_request_log)

        # 注册错误信息
        self.__setup_error_handler(app)

        # 注册蓝图
        self.__register_bp(app)

        self.log.info("flask 服务初始化完成...")
        return app

    # 注册蓝图
    @staticmethod
    def __register_bp(app):
        # 工商接口
        app.register_blueprint(gsxt_bp)

        # 新闻接口
        app.register_blueprint(news_bp)

        # 失信接口
        app.register_blueprint(shixin_bp)

        # 执行信息
        app.register_blueprint(zhixing_bp)

        # 裁判文书
        app.register_blueprint(wenshu_bp)

    def __print_request_log(self, resp, *args, **kwargs):
        self.log.info('ip: {ip} request: [{status}] {method}, '
                      'url: {url} req: {req}'.format(ip=self.__get_remote_addr(),
                                                     status=resp.status,
                                                     method=request.method,
                                                     url=request.url,
                                                     req=json.dumps(request.json, ensure_ascii=False)))
        # self.log.info("----headers----")
        # self.log.info(request.headers)
        # 不是debug模式下也需要打印数据信息
        # if resp.mimetype == 'application/json':
        #     data = resp.get_data()
        #     self.log.info("response: {}".format(json.dumps(json.loads(data), ensure_ascii=False)))
        return resp

    @staticmethod
    def __get_remote_addr():
        return request.headers.get('X-Real-Ip', request.remote_addr)

    def __setup_error_handler(self, app):
        def log_error(e):
            self.log.warn(
                '{addr} request: {method}, '
                'url: {url}'.format(addr=self.__get_remote_addr(),
                                    method=request.method,
                                    url=request.url))
            self.log.warn("{}".format(request.headers))
            self.log.exception(e)

        @app.errorhandler(400)
        @app.errorhandler(ValueError)
        def http_bad_request(e):
            log_error(e)
            return ResponseWrap.fail(ResponseWrap.HTTP_BAD_REQUEST)

        @app.errorhandler(403)
        def http_forbidden(e):
            log_error(e)
            return ResponseWrap.fail(ResponseWrap.HTTP_FORBIDDEN)

        @app.errorhandler(404)
        def http_not_found(e):
            log_error(e)
            return ResponseWrap.fail(ResponseWrap.HTTP_NOT_FOUND)

        @app.errorhandler(500)
        @app.errorhandler(Exception)
        def http_server_error(e):
            log_error(e)
            return ResponseWrap.fail(ResponseWrap.HTTP_SERVER_ERROR)
